//===============================================================================
// Microsoft patterns & practices
// Mobile Client Software Factory - July 2006
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;

namespace Microsoft.Practices.Mobile.ConnectionMonitor
{
	/// <summary>
	///		This class has the responsibility to manage the connections and networks, and
	///		the connected status of the device.
	/// </summary>
	/// <remarks>
	///		The monitor has a connections collection.
	///		It wires the added connections to get the connection status changes
	///		and you can get the current Network from a connected connection.
	///		It also publishes the connection status of the device through the <see cref="IsConnected"/>
	///		property, and an <see cref="ConnectionStatusChanged"/> event to inform the subscribers when
	///		the connectivity status has changed in any of the registered connections.
	/// </remarks>
	public class ConnectionMonitor
	{
		private ConnectionCollection connections;
		private EventHandler<StateChangedEventArgs> onStateChanged;



		/// <summary>
		/// This event is fired when the connectivity status has changed.
		/// </summary>
		public event EventHandler ConnectionStatusChanged;

		/// <summary>
		/// Constructor of the <see cref="ConnectionMonitor"/> class.
		/// </summary>
		public ConnectionMonitor()
		{
			connections = new ConnectionCollection(this);
			onStateChanged = OnStateChanged;
		}

		/// <summary>
		/// Get the connections collection.
		/// </summary>
		public ConnectionCollection Connections
		{
			get { return connections; }
		}

		/// <summary>
		/// Get active connections.
		/// </summary>
		public IEnumerable<Connection> ActiveConnections
		{
			get
			{
				foreach (Connection con in connections)
				{
					if (con.IsConnected)
						yield return con;
				}
			}
		}


		internal void ConnectionAdded(Connection connection)
		{
			connection.StateChanged += onStateChanged;
			connection.UpdateStatus();
		}

		/// <summary>
		/// Gets if the device is connected according to the ConnectionMonitor connections.
		/// </summary>
		public bool IsConnected
		{
			get 
			{
				foreach (Connection con in connections)
				{
					if (con.IsConnected)
						return true;
				}
				return false;
			}
		}


		private void OnStateChanged(object sender, StateChangedEventArgs args)
		{
			if (ConnectionStatusChanged != null)
			{
				ConnectionStatusChanged(this, EventArgs.Empty);
			}
		}

		internal void ConnectionRemoved(Connection connection)
		{
			connection.StateChanged -= onStateChanged;
		}
	}
}
